package com.wxzz.elearing.course.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.wxzz.elearing.course.amqp.producer.CourseProducer;
import com.wxzz.elearing.course.dto.*;
import com.wxzz.elearing.course.entity.*;
import com.wxzz.elearing.course.mapper.*;
import com.wxzz.elearing.course.service.ICurriculumSectionTopicService;
import com.wxzz.elearing.course.service.IExamServiceService;
import com.wxzz.elearing.course.service.openfeign.IWxUserApiFeign;
import com.wxzz.elearning.common.aop.Idempotent;
import com.wxzz.elearning.common.dto.SystemMessageMqDto;
import com.wxzz.elearning.common.exception.ServiceException;
import com.wxzz.elearning.common.utils.OpenFeignUtil;
import com.wxzz.elearning.common.vo.JgPageVo;
import com.wxzz.elearning.common.vo.ReturnVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

@Service


public class ExamServiceServiceImpl extends ServiceImpl<ExamMapper, Exam> implements IExamServiceService {

    @Autowired
    private ExamMapper examMapper;

    @Override
    public ReturnVO<JgPageVo<List<Exam>>> listExamByEnterpriseId(Long enterpriseId, ExamDto examDto) {
        PageHelper.startPage(examDto.getCurPage(), examDto.getMaxPage());
        QueryWrapper<Exam> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("create_time");
        queryWrapper.eq("enterprise_id", enterpriseId);
        if (StringUtils.isNotBlank(examDto.getExamName())) {
            queryWrapper.like("exam_name", examDto.getExamName());
        }
        List<Exam> exams = examMapper.selectList(queryWrapper);
        for (Exam exam : exams) {
            exam.setTestPersonNum(wxUserExamMapper.selectCount(new LambdaQueryWrapper<WxUserExam>()
                    .eq(WxUserExam::getExamId, exam.getId())));
            Integer passCount = wxUserExamHistoryMapper.selectCount(new LambdaQueryWrapper<WxUserExamHistory>()
                    .eq(WxUserExamHistory::getExamId, exam.getId())
                    .eq(WxUserExamHistory::getIsPass, 1));
            Integer allCount = wxUserExamHistoryMapper.selectCount(new LambdaQueryWrapper<WxUserExamHistory>()
                    .eq(WxUserExamHistory::getExamId, exam.getId()));
            exam.setTestNum(passCount);
            if (!allCount.equals(0)) {
                exam.setPassProbability((double) passCount / allCount * 100);
            }
        }
        return new ReturnVO<>("在线考试查询成功", new JgPageVo<>(new PageInfo(exams)));
    }

    @Autowired
    private CurriculumSectionTopicMapper curriculumSectionTopicMapper;

    @Autowired
    private CurriculumSectionTopicAnswerMapper curriculumSectionTopicAnswerMapper;

    @Override
    public ReturnVO saveExam(Exam exam) {
        if (exam.getId() == null) {
            examMapper.insert(exam);
        } else {
            //更新 将原有的试题删除重新添加
            examMapper.updateById(exam);
            List<CurriculumSectionTopic> curriculumSectionTopics = curriculumSectionTopicMapper.selectList(new LambdaQueryWrapper<CurriculumSectionTopic>()
                    .eq(CurriculumSectionTopic::getCurriculumSectionId, exam.getId()));
            curriculumSectionTopics.forEach(curriculumSectionTopic -> {
                //删除试题
                curriculumSectionTopicMapper.deleteById(curriculumSectionTopic.getId());
                //删除答案
                curriculumSectionTopicAnswerMapper.deleteCurriculumSectionTopicAnswerByCurriculumSectionTopicId(curriculumSectionTopic.getId());
            });
        }
        if (exam.getCurriculumSectionTopics() != null) {
            //添加试题
            for (CurriculumSectionTopic curriculumSectionTopic : exam.getCurriculumSectionTopics()) {
                curriculumSectionTopic.setId(null);
                curriculumSectionTopic.setCurriculumSectionId(exam.getId());
                curriculumSectionTopic.setTopicCategory(1);
                curriculumSectionTopicMapper.insert(curriculumSectionTopic);
                if (curriculumSectionTopic.getCurriculumSectionTopicAnswerList() != null) {
                    //添加试题答案选项
                    curriculumSectionTopic.getCurriculumSectionTopicAnswerList().forEach(curriculumSectionTopicAnswer -> {
                        curriculumSectionTopicAnswer.setId(null);
                        curriculumSectionTopicAnswer.setCurriculumSectionTopicId(curriculumSectionTopic.getId());
                        curriculumSectionTopicAnswerMapper.insert(curriculumSectionTopicAnswer);
                    });
                }
            }
        }
        return new ReturnVO("课程章节新增或修改成功", exam.getId());
    }

    @Override
    public ReturnVO deleteExam(Long examId) {
        examMapper.deleteById(examId);
        return new ReturnVO("考试删除成功", examId);
    }

    @Autowired
    private ICurriculumSectionTopicService curriculumSectionTopicService;

    @Override
    public ReturnVO selectExamDetailById(Long examId) {
        Exam exam = examMapper.selectById(examId);
        Optional.ofNullable(exam).orElseThrow(() -> new ServiceException("该考试id对应考试不存在"));
        //查询测评试题
        ReturnVO<List<CurriculumSectionTopic>> listReturnVO = curriculumSectionTopicService.listCurriculumSectionTopicByCurriculumSectionTopicId(examId, 1);
        exam.setCurriculumSectionTopics(listReturnVO.getData());
        //题目数量
        exam.setTopicNum(listReturnVO.getData().size());
        //总分
        BigDecimal topicAllScore = new BigDecimal("0.00");
        for (CurriculumSectionTopic datum : listReturnVO.getData()) {
            List<CurriculumSectionTopicAnswer> curriculumSectionTopicAnswerList = datum.getCurriculumSectionTopicAnswerList();
            for (CurriculumSectionTopicAnswer curriculumSectionTopicAnswer : curriculumSectionTopicAnswerList) {
                topicAllScore = topicAllScore.add(curriculumSectionTopicAnswer.getScore());
            }
        }
        exam.setTopicAllScore(topicAllScore);
        exam.setTestPersonNum(wxUserExamMapper.selectCount(new LambdaQueryWrapper<WxUserExam>()
                .eq(WxUserExam::getExamId, exam.getId())));
        Integer passCount = wxUserExamHistoryMapper.selectCount(new LambdaQueryWrapper<WxUserExamHistory>()
                .eq(WxUserExamHistory::getExamId, exam.getId())
                .eq(WxUserExamHistory::getIsPass, 1));
        Integer allCount = wxUserExamHistoryMapper.selectCount(new LambdaQueryWrapper<WxUserExamHistory>()
                .eq(WxUserExamHistory::getExamId, exam.getId()));
        exam.setTestNum(passCount);
        if (!allCount.equals(0)) {
            exam.setPassProbability((double) passCount / allCount * 100);
        }
        return new ReturnVO("考试详情查询成功", exam);
    }


    @Autowired
    private IWxUserApiFeign wxUserApiFeign;

    @Override
    public ReturnVO<JgPageVo<List<WxUserExam>>> selectWxUserExamByExamId(WxUserExamByExamIDto wxUserExamByExamIDto) {
        PageHelper.startPage(wxUserExamByExamIDto.getCurPage(), wxUserExamByExamIDto.getMaxPage());
        List<WxUserExam> wxUserExams = wxUserExamMapper.selectList(new LambdaQueryWrapper<WxUserExam>()
                .eq(WxUserExam::getExamId, wxUserExamByExamIDto.getExamId())
                .eq(WxUserExam::getExamStatus, 0));
        for (WxUserExam wxUserExam : wxUserExams) {
            //查询用户信息
            ReturnVO<String> stringReturnVO = wxUserApiFeign.selectWxUserByWxUserId(wxUserExam.getWxUserId());
            JSONObject jsonObject = OpenFeignUtil.getJSONObject(stringReturnVO);
            wxUserExam.setNickname(jsonObject.getString("nickname"));
            wxUserExam.setIcon(jsonObject.getString("icon"));
            wxUserExam.setPhone(jsonObject.getString("phone"));
            wxUserExam.setOrganizationName(jsonObject.getString("organizationName"));
            wxUserExam.setIdentityName(jsonObject.getString("identityName"));
        }
        return new ReturnVO("考试人员查询成功", new JgPageVo<>(new PageInfo(wxUserExams)));
    }

    @Idempotent
    @Override
    public ReturnVO saveWxUserExam(WxUserExamInsDto wxUserExamInsDto) {
        Exam exam = examMapper.selectById(wxUserExamInsDto.getExamId());
        Optional.ofNullable(exam).orElseThrow(() -> new ServiceException("该考试id对应考试不存在"));
        if (wxUserExamInsDto.getWxUserIds() != null) {
            //先全部禁考
            List<WxUserExam> wxUserExams = wxUserExamMapper.selectList(new LambdaQueryWrapper<WxUserExam>()
                    .eq(WxUserExam::getExamStatus, 0)
                    .eq(WxUserExam::getExamId, exam.getId()));
            for (WxUserExam wxUserExam : wxUserExams) {
                //禁考
                wxUserExam.setExamStatus(1);
                wxUserExamMapper.updateById(wxUserExam);
            }
            //重新分配
            for (Long wxUserId : wxUserExamInsDto.getWxUserIds()) {
                WxUserExam wxUserExam = wxUserExamMapper.selectOne(new LambdaQueryWrapper<WxUserExam>()
                        .eq(WxUserExam::getExamId, wxUserExamInsDto.getExamId())
                        .eq(WxUserExam::getWxUserId, wxUserId));
                //如果不存在则添加上去
                if (wxUserExam == null) {
                    WxUserExam save = new WxUserExam();
                    save.setExamId(exam.getId());
                    save.setWxUserId(wxUserId);
                    wxUserExamMapper.insert(save);
                } else {
                    //如果存在则直接改为可考
                    wxUserExam.setExamStatus(0);
                    wxUserExamMapper.updateById(wxUserExam);
                }
            }
            //todo 小程序订阅
            SystemMessageMqDto systemMessageMqDto = new SystemMessageMqDto();
            systemMessageMqDto.setMessageDetail("您已被纳入" + exam.getExamName() + "在线考试中,请及时完成考试");
            systemMessageMqDto.setMessageTitle("在线考试");
            systemMessageMqDto.setWxUserIds(wxUserExamInsDto.getWxUserIds());
            courseProducer.ackMQSender(JSONObject.toJSONString(systemMessageMqDto));
        }
        return new ReturnVO("考试人员分配成功", exam.getId());
    }

    @Autowired
    private CourseProducer courseProducer;

    @Override
    public ReturnVO<JgPageVo<List<Exam>>> listExamByWxUserId(Long wxUserId, ExamByWxUserIdDto examByWxUserIdDto) {
        PageHelper.startPage(examByWxUserIdDto.getCurPage(), examByWxUserIdDto.getMaxPage());
        List<Exam> exams = examMapper.listExamByWxUserId(wxUserId, examByWxUserIdDto);
        for (Exam exam : exams) {
            Integer count = curriculumSectionTopicMapper.selectCount(new LambdaQueryWrapper<CurriculumSectionTopic>()
                    .eq(CurriculumSectionTopic::getTopicType, 1)
                    .eq(CurriculumSectionTopic::getCurriculumSectionId, exam.getId()));
            exam.setTopicNum(count);
        }
        return new ReturnVO("考试查询成功", new JgPageVo<>(new PageInfo(exams)));
    }

    @Override
    public ReturnVO<List<WxUserExamHistory>> listExamByExamHistory(Long wxUserId, Long examId) {
        List<WxUserExamHistory> wxUserExamHistories = wxUserExamHistoryMapper.selectList(new LambdaQueryWrapper<WxUserExamHistory>()
                .eq(WxUserExamHistory::getWxUserId, wxUserId)
                .eq(WxUserExamHistory::getExamId, examId)
                .orderByDesc(WxUserExamHistory::getCreateTime));
        for (WxUserExamHistory wxUserExamHistory : wxUserExamHistories) {
            wxUserExamHistory.setCurriculumSectionTopics(JSONObject.parseArray(wxUserExamHistory.getTopicJson(), CurriculumSectionTopic.class));
            wxUserExamHistory.setTopicJson("");
        }
        return new ReturnVO("考试记录查询成功", wxUserExamHistories);
    }

    @Autowired
    private WxUserExamHistoryMapper wxUserExamHistoryMapper;

    @Autowired
    private WxUserExamMapper wxUserExamMapper;

    @Override
    public ReturnVO<WxUserExamHistory> examIsPass(Long wxUserId, ExamIsPassDto examIsPassDto) {
        BigDecimal allScore = new BigDecimal("0.00");
        //计算分数
        for (CurriculumSectionTopic curriculumSectionTopic : examIsPassDto.getCurriculumSectionTopics()) {
            String choose = "";
            List<CurriculumSectionTopicAnswer> curriculumSectionTopicAnswers = curriculumSectionTopic.getCurriculumSectionTopicAnswerList();
            //取出答案
            for (CurriculumSectionTopicAnswer curriculumSectionTopicAnswer : curriculumSectionTopicAnswers) {
                //取出选项的分数
                if (Boolean.TRUE.equals(curriculumSectionTopicAnswer.getIsChoose())) {
                    if (curriculumSectionTopicAnswer.getScore() != null) {
                        allScore = allScore.add(curriculumSectionTopicAnswer.getScore());
                    }
                    choose = choose + curriculumSectionTopicAnswer.getItem() + ",";
                }
            }
            curriculumSectionTopic.setItems(choose);
        }

        WxUserExamHistory wxUserExamHistory = new WxUserExamHistory();
        //设置总分
        wxUserExamHistory.setAllScore(allScore);
        wxUserExamHistory.setExamId(examIsPassDto.getExamId());
        wxUserExamHistory.setWxUserId(wxUserId);
        wxUserExamHistory.setUseTime(examIsPassDto.getUseTime());
        //验证是否通过
        Exam exam = examMapper.selectById(examIsPassDto.getExamId());
        if (exam == null) {
            throw new ServiceException("该考试不存在");
        } else {
            if (wxUserExamHistory.getAllScore().compareTo(exam.getQualified()) == 1 || wxUserExamHistory.getAllScore().compareTo(exam.getQualified()) == 0) {
                //如果总分数大于等于合格分数
                wxUserExamHistory.setIsPass(1);
                //修改为已通过
                WxUserExam wxUserExam = wxUserExamMapper.selectOne(new LambdaQueryWrapper<WxUserExam>()
                        .eq(WxUserExam::getExamId, examIsPassDto.getExamId())
                        .eq(WxUserExam::getWxUserId, wxUserId));
                wxUserExam.setIsPass(1);
                wxUserExamMapper.updateById(wxUserExam);
            } else {
                wxUserExamHistory.setIsPass(0);
            }
        }
        if (examIsPassDto.getCurriculumSectionTopics() != null) {
            wxUserExamHistory.setTopicJson(JSONObject.toJSONString(examIsPassDto.getCurriculumSectionTopics()));
        }
        //添加考试记录
        wxUserExamHistoryMapper.insert(wxUserExamHistory);
        return new ReturnVO("考试测试完毕", wxUserExamHistory);
    }

    @Override
    public ReturnVO<List<CurriculumSectionTopic>> selectCurriculumSectionTopicByExamHistoryId(Long wxUserExamHistoryId) {
        WxUserExamHistory wxUserExamHistory = wxUserExamHistoryMapper.selectById(wxUserExamHistoryId);
        return new ReturnVO("考试测试完毕", JSONObject.parseArray(wxUserExamHistory.getTopicJson()));
    }

    @Override
    public ReturnVO<JgPageVo<List<WxUserExamHistory>>> wxListWxUserExamHistory(Long wxUserId, WxUserExamHistoryDto wxUserExamHistoryDto) {
        PageHelper.startPage(wxUserExamHistoryDto.getCurPage(), wxUserExamHistoryDto.getMaxPage());
        QueryWrapper<WxUserExamHistory> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("wx_user_id", wxUserId);
        if (wxUserExamHistoryDto.getExamId() != null) {
            queryWrapper.eq("exam_id", wxUserExamHistoryDto.getExamId());
        }
        List<WxUserExamHistory> wxUserExamHistories = wxUserExamHistoryMapper.selectList(queryWrapper);
        for (WxUserExamHistory wxUserExamHistory : wxUserExamHistories) {
            Exam exam = examMapper.selectById(wxUserExamHistory.getExamId());
            Optional.ofNullable(exam).ifPresent(e -> {
                Integer count = curriculumSectionTopicMapper.selectCount(new LambdaQueryWrapper<CurriculumSectionTopic>()
                        .eq(CurriculumSectionTopic::getTopicType, 1)
                        .eq(CurriculumSectionTopic::getCurriculumSectionId, e.getId()));
                wxUserExamHistory.setTopicNum(count);
                wxUserExamHistory.setExamBanner(e.getExamBanner());
                wxUserExamHistory.setExamName(e.getExamName());
                wxUserExamHistory.setScheduledTime(e.getScheduledTime());
            });
        }
        return new ReturnVO("查询我的考试记录成功", new JgPageVo<>(new PageInfo(wxUserExamHistories)));
    }

    @Override
    public ReturnVO<List<JSONObject>> selectWxUserExam(Long examId, List<Long> wxUserIds) {
        List<JSONObject> wxUserExams = Lists.newArrayList();
        for (Long wxUserId : wxUserIds) {
            //查询用户绑定可考的考试
            WxUserExam wxUserExam = wxUserExamMapper.selectOne(new LambdaQueryWrapper<WxUserExam>()
                    .eq(WxUserExam::getExamId, examId)
                    .eq(WxUserExam::getWxUserId, wxUserId)
                    .eq(WxUserExam::getExamStatus, 0));
            if (wxUserExam != null) {
                wxUserExams.add(JSONObject.parseObject(JSONObject.toJSONString(wxUserExam)));
            }
        }
        return new ReturnVO("考试绑定人员查询成功", wxUserExams);
    }
}
